#ifndef __PROCESS_POOL_HPP__
#define __PROCESS_POOL_HPP__

#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <cstring>
#include <stdlib.h>
#include <vector>
#include <ctime> // 用于随机数种子

using namespace std;

// 任务函数声明（原depend.hpp中的内容，直接包含避免依赖问题）
typedef void (*task_t)();
void PrintLog() { cout << "我是一个打印日志的任务" << endl; }
void Download() { cout << "我是一个下载的任务" << endl; }
void Upload() { cout << "我是一个上传的任务" << endl; }

// 修正类名拼写（Mananger → Manager）
class TaskManager
{
private:
    vector<task_t> _tasks;

public:
    TaskManager()
    {
        // 随机数种子仅初始化一次（放在构造函数中，若多实例需移至main）
        static bool is_seeded = false;
        if (!is_seeded)
        {
            srand(time(nullptr));
            is_seeded = true;
        }
    }

    void Register(task_t t) { _tasks.push_back(t); }

    int Code()
    {
        if (_tasks.empty())
            return -1; // 避免空容器取模
        return rand() % _tasks.size();
    }

    void Execute(int code)
    {
        if (code >= 0 && code < _tasks.size())
        {
            _tasks[code]();
        }
    }
};

class channel
{
public:
    channel(int wfd, pid_t subid) : _wfd(wfd), _subid(subid)
    {
        _name = "channel-" + to_string(_wfd) + "-" + to_string(_subid);
    }

    ~channel() = default;

    void Send(int code)
    {
        ssize_t n = write(_wfd, &code, sizeof(code));
        if (n != sizeof(code))
        {
            cerr << "发送失败[" << _name << "]: " << strerror(errno) << endl;
        }
    }

    void Close() { close(_wfd); }

    void Wait() { waitpid(_subid, nullptr, 0); }

    int Fd() { return _wfd; }
    pid_t Subid() { return _subid; }
    string name() { return _name; }

private:
    int _wfd;
    pid_t _subid;
    string _name;
};

// 修正类名拼写（ChannelMananger → ChannelManager）
class ChannelManager
{
public:
    ChannelManager() : _next(0) {}

    void insert(int wfd, pid_t subid) { _channels.emplace_back(wfd, subid); }

    channel &select()
    {
        auto &c = _channels[_next++];
        _next %= _channels.size();
        return c;
    }

    void PrintChannel()
    {
        for (auto &x : _channels)
        {
            cout << x.name() << endl;
        }
    }
    void CloseAll()
    {
        for (auto &x : _channels)
        {
            x.Close();
        }
    }
    void StopSubProcess()
    {
        for (auto &x : _channels)
        {
            x.Close();
            cout << "关闭" << x.name() << endl; 
        }
    }

    void WaitSubProcess()
    {
        for (auto &x : _channels)
        {
            x.Wait();
            cout << "回收" << x.name() << endl;
        }
    }

private:
    vector<channel> _channels;
    int _next;
};

struct ProcessPool
{
    ProcessPool(int num) : _process_num(num)
    {
        // 父进程注册任务（子进程会独立初始化，这里仅用于生成任务码）
        _tm.Register(PrintLog);
        _tm.Register(Download);
        _tm.Register(Upload);
    }

    // 子进程工作函数：接收任务码并执行任务
    void work(int rfd)
    {
        // 子进程必须独立初始化任务管理器并注册任务（进程间内存不共享）
        TaskManager local_tm;
        local_tm.Register(PrintLog);
        local_tm.Register(Download);
        local_tm.Register(Upload);

        while (true)
        {
            int code = 0;
            ssize_t n = read(rfd, &code, sizeof(code));
            if (n > 0)
            {
                if (n != sizeof(code))
                    continue; // 忽略不完整数据
                cout << "子进程[" << getpid() << "] 收到任务码: " << code << endl;
                local_tm.Execute(code); // 执行对应任务
            }
            else if (n == 0)
            {
                cout << "子进程[" << getpid() << "] 退出" << endl;
                break;
            }
            else
            {
                cerr << "子进程[" << getpid() << "] 读取错误: " << strerror(errno) << endl;
                break;
            }
        }
        close(rfd); // 释放资源
    }

    bool start()
    {
        for (int i = 0; i < _process_num; ++i)
        {
            int pipefd[2];
            if (pipe(pipefd) < 0)
            {
                cerr << "管道创建失败: " << strerror(errno) << endl;
                return false;
            }

            pid_t subid = fork();
            if (subid < 0)
            {
                cerr << "进程创建失败: " << strerror(errno) << endl;
                close(pipefd[0]);
                close(pipefd[1]);
                return false;
            }
            else if (subid == 0)
            {
                _cm.CloseAll();   // 子进程
                close(pipefd[1]); // 关闭写端
                work(pipefd[0]);
                close(pipefd[0]);
                exit(0);
            }
            else
            {                     // 父进程
                close(pipefd[0]); // 关闭读端
                _cm.insert(pipefd[1], subid);
            }
        }
        return true;
    }

    void Debug() { _cm.PrintChannel(); }

    void Run()
    {
        int taskcode = _tm.Code();
        auto &c = _cm.select();
        cout << "选择进程: " << c.name() << endl;
        c.Send(taskcode);
        cout << "发送任务码: " << taskcode << endl;
    }

    void Stop()
    {
        _cm.StopSubProcess();
        _cm.WaitSubProcess();
        sleep(1);
    }

private:
    ChannelManager _cm;
    int _process_num;
    TaskManager _tm; // 父进程用于生成任务码
};

#endif